<template>
  <div id="threeDome"></div>
</template>

<script setup>
  import { onMounted } from 'vue'
  // 导入threejs
  import * as THREE from 'three'
  // 导入控制器
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
  // 导入lil.gui
  import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'

  // 定义需要全局的变量
  let parentMaterial, material, parentCube, cube;

  onMounted(() => {
    initThree()
  })

  const initThree = () => {
    // 创建创景
    const scene = new THREE.Scene()
    // 创建相机
    const camera = new THREE.PerspectiveCamera(
        45, // 视角
        window.innerWidth / window.innerHeight, // 宽高比
        0.1, // 近平面
        1000 // 远平面
    )
    // 创建渲染器
    const renderer = new THREE.WebGLRenderer()
    renderer.setSize(window.innerWidth, window.innerHeight)
    // 添加画布到dom中
    document.querySelector('#threeDome').appendChild(renderer.domElement)

    // 创建几何体
    parentCube = new THREE.BufferGeometry()
    // 设置顶点数据方法1：顶点是有序的，每三个为一个顶点，逆时针为正面，不共享点共有6个顶点
    // const vertices = new Float32Array([
    //   // 左下角
    //   -1, -1, 0,
    //   // 右下角
    //   1, -1, 0,
    //   // 右上角
    //   1, 1, 0,
    //   // 右上角
    //   1, 1, 0,
    //   // 左上角
    //   -1, 1, 0,
    //   // 左下角
    //   -1, -1, 0
    // ])
    // 创建顶点属性
    // parentCube.setAttribute('position', new THREE.BufferAttribute(vertices, 3))

    // 设置顶点数据方法2：使用索引绘制顶点数据，共享点共有4个顶点
    const vertices = new Float32Array([
      // 左下角
      -1, -1, 0,
      // 右下角
      1, -1, 0,
      // 右上角
      1, 1, 0,
      // 左上角
      -1, 1, 0
    ])
    // 创建顶点属性
    parentCube.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
    // 创建索引
    const indices = new Uint16Array([
      0, 1, 2,
      2, 3, 0
    ])
    parentCube.setIndex(new THREE.BufferAttribute(indices, 1))

    // 创建材质
    parentMaterial = new THREE.MeshBasicMaterial({
      color: 0xff0000,
      side: THREE.DoubleSide, // 两面都可以看到
      wireframe: true
    })
    const plane = new THREE.Mesh(parentCube, parentMaterial)


    // 将网格添加到场景中
    scene.add(plane)

    // 设置相机位置
    camera.position.z = 5
    camera.position.x = 2
    camera.position.y = 2
    // 看向哪里(默认看向原点0)
    camera.lookAt(0, 0, 0)

    // 添加时间坐标辅助器
    const axesHelper = new THREE.AxesHelper(3 )
    // 把坐标器添加到场景中
    scene.add(axesHelper)

    // 添加轨道控制器(加入控制器后模型就可以鼠标拖动了，实际上控制的是相机视角，相机绕着物体旋转)
    const controls = new OrbitControls(camera, renderer.domElement)
    // 设置带阻尼的惯性（拖动后有一个缓动）
    controls.enableDamping = true
    // 设置阻尼系数（就是拖动鼠标松开后惯性的大小，时间长久，数字越小惯性越大）
    controls.dampingFactor = 0.05

    // 创建GUI
    const gui = new GUI()
    // 创建gui按钮
    const eventObj = {
      Fullscreen: function () {
        document.body.requestFullscreen()
      },
      ExitFullscreen: function () {
        if (!document.fullscreenElement) return
        document.exitFullscreen()
      }
    }
    // 添加全屏按钮
    gui.add(eventObj, 'Fullscreen').name('全屏')
    gui.add(eventObj, 'ExitFullscreen').name('退出全屏')

    // 渲染函数
    function animate() {
      gui.updateGuards
      controls.update()
      requestAnimationFrame(animate)
      // 渲染
      renderer.render(scene, camera)
    }
    animate()

    // 监听窗口变化
    window.addEventListener('resize', () => {
      // 重置渲染器宽高比
      renderer.setSize(window.innerWidth, window.innerHeight)
      // 重置相机宽高比和投影矩阵
      camera.aspect = window.innerWidth / window.innerHeight
      // 更新相机投影矩阵
      camera.updateProjectionMatrix()
    })
  }



</script>

<style scoped>
  
</style>
